package main

import (
	"fmt"

	"gitee.com/doraemon1996/bunny/network"
	"github.com/gorilla/websocket"
)

type Encoder struct {
}

func (enc *Encoder) encode_TCP(_ network.Conn, msg any) (pkt []byte, err error) {
	pkt = []byte(msg.(string))
	return
}

func (enc *Encoder) encode_UDP(_ network.Conn, msg any) (pkt []byte, err error) {
	p := msg.(*network.UDPPacket)
	pkt = []byte(p.Message.(string))
	return
}

func (enc *Encoder) encode_WS(_ network.Conn, msg any) (pkt []byte, err error) {
	p := msg.(*network.WSPacket)
	switch p.MessageType {
	case websocket.TextMessage, websocket.BinaryMessage:
		str := p.Message.(string)
		pkt = []byte(str)
	default:
		err = fmt.Errorf("unsupport message type %v", p.MessageType)
		return
	}
	return
}

func (enc *Encoder) decode_TCP(_ network.Conn, pkt any) (msg any, length int, err error) {
	buf := pkt.([]byte)
	msg = string(buf)
	length = len(buf)
	return
}

func (enc *Encoder) decode_UDP(_ network.Conn, pkt any) (msg any, length int, err error) {
	p := pkt.(*network.UDPPacket)
	buf := p.Message.([]byte)
	p.Message = string(buf)
	length = len(buf)
	msg = p
	return
}

func (enc *Encoder) decode_WS(_ network.Conn, pkt any) (msg any, length int, err error) {
	p := pkt.(*network.WSPacket)
	switch p.MessageType {
	case websocket.TextMessage, websocket.BinaryMessage:
		buf := p.Message.([]byte)
		p.Message = string(buf)
		length = len(buf)
		msg = p
	default:
		err = fmt.Errorf("unsupport message type %v", p.MessageType)
		return
	}
	return
}

// 消息编码
func (enc *Encoder) Encode(conn network.Conn, msg any) (pkt []byte, err error) {
	switch conn.Type() {
	case network.Connection_TCP:
		return enc.encode_TCP(conn, msg)
	case network.Connection_UDP:
		return enc.encode_UDP(conn, msg)
	case network.Connection_WS, network.Connection_WSS:
		return enc.encode_WS(conn, msg)
	default:
		err = fmt.Errorf("unsupport connection type %v", conn.Type())
		return
	}
}

// 消息解码
func (enc *Encoder) Decode(conn network.Conn, pkt any) (msg any, length int, err error) {
	switch conn.Type() {
	case network.Connection_TCP:
		return enc.decode_TCP(conn, pkt)
	case network.Connection_UDP:
		return enc.decode_UDP(conn, pkt)
	case network.Connection_WS, network.Connection_WSS:
		return enc.decode_WS(conn, pkt)
	default:
		err = fmt.Errorf("unsupport connection type %v", conn.Type())
		return
	}
}
